/*
 * This file is part of Cadmium.
 * Copyright (C) 2007-2010 Xavier Clerc.
 *
 * Cadmium is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Cadmium is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package fr.x9c.cadmium.primitives.zip;

import java.util.zip.Deflater;
import java.util.zip.Inflater;

import fr.x9c.cadmium.kernel.Block;
import fr.x9c.cadmium.kernel.Value;

/**
 * This class implements a ZStream, that is a object that encapsulates
 * either an inflater or a deflater.
 *
 * @author <a href="mailto:cadmium@x9c.fr">Xavier Clerc</a>
 * @version 1.0
 * @since 1.0
 */
final class ZStream {

    /** Size of abstract block for streams. */
    private static final int BLOCK_SIZE = 1;

    /**
     * Underlying deflater (can be <tt>null</tt>, in that case the inflater is
     * non-<tt>null</tt>).
     */
    private final Deflater deflater;

    /**
     * Underlying inflater (can be <tt>null</tt>, in that case the deflater is
     * non-<tt>null</tt>).
     */
    private final Inflater inflater;

    /**
     * Constructs a stream from either an inflater or a deflater. <br/>
     * One of the two arguments should be <tt>null</tt> and the other
     * non-<tt>null</tt>.
     * @param d deflater
     * @param i inflater
     */
    private ZStream(final Deflater d, final Inflater i) {
        assert (d != null) ^ (i != null) : "either i or d should be (not-)null";
        this.deflater = d;
        this.inflater = i;
    } // end constructor(Deflater, Inflater)

    /**
     * Constructs a value encapsulating a stream (as an abstract value)
     * from either an inflater or a deflater. <br/>
     * One of the two arguments should be <tt>null</tt> and the other
     * non-<tt>null</tt>.
     * @param d deflater
     * @param i inflater
     * @return a new stream
     */
    static Value create(final Deflater d, final Inflater i) {
        assert (d != null) ^ (i != null) : "either i or d should be (not-)null";
        final Block res = Block.createBlock(ZStream.BLOCK_SIZE,
                                            Block.ABSTRACT_TAG);
        res.setCustom(new ZStream(d, i));
        return Value.createFromBlock(res);
    } // end method 'create(Deflater, Inflater)'

    /**
     * Returns the underlying deflater.
     * @return the underlying deflater
     */
    Deflater getDeflater() {
        return this.deflater;
    } // end method 'getDeflater()'

    /**
     * Returns the underlying inflater.
     * @return the underlying inflater
     */
    Inflater getInflater() {
        return this.inflater;
    } // end method 'getInflater()'

} // end class 'ZStream'
